#ifndef CANDRIVER_H
#define CANDRIVER_H

#include <QMutex>
#include <QThread>
#include <QQueue>
#include <QObject>

#include "ControlCAN.h"

#define EN_VECTOR
#define EN_ZLGCAN
// #define EN_PCAN

#if !defined(DEF_CAN_OBJ)
typedef struct
{
    uint32_t bExtern    :1;
    uint32_t bRemote    :1;
    uint32_t ID         :30;

    uint8_t  uLen;

    uint8_t  Data[8];

    uint64_t TimePrev;      //
    uint64_t TimeStamp;     //时间戳(us),

        uint8_t  bDir;          //
    uint8_t  uCh;           //
    uint8_t  uChange;       //数据有变化
} sCANObj;

typedef struct{
    uint    nBaud;
    bool    bUserDefBaud;       //用户定义波特率
    uint8_t uBTR0;
    uint8_t uBTR1;
}sCanBaud;
#endif

class CanDriver : public QObject
{
    Q_OBJECT
public:
    CanDriver();
    virtual bool OpenDevice(QString sDevName,const sCanBaud mBaud) = 0;
    virtual bool CloseDevice() = 0;
    virtual bool SetBaud(uint32_t uBaud) = 0;
    virtual bool FindDev(QStringList &DevList) = 0;
    virtual bool Send(const sCANObj &msg) = 0;
    virtual int Receive(sCANObj &msg,DWORD dwMilliseconds) = 0;
    virtual ULONG GetSta(void) = 0;
    uint32_t uAck;
    uint32_t uMask;
};

typedef struct{
    QString sBaud;
    uint    uBaud;
    uint8_t uBTR0;
    uint8_t uBTR1;
}sZLGTime;

extern sZLGTime mZLGTimeList[15];

typedef struct{
    const char*   sName;      //设备名称
    uint    uDevNum;    //设备编号
    uint    uPortNum;   //端口数据
}sCanDev;

#ifdef EN_ZLGCAN
class ZlgCanSnd : public QThread
{
    Q_OBJECT
public:
    ZlgCanSnd();

    void run();
public:
    int m_devtype;
    int m_DevInd;
    int m_PortInd;
    bool bRun = false;
    HANDLE hTxEvent;
    HANDLE hTxFinishEvent;
    QMutex mutex;
    QQueue<sCANObj> mSndFifo;
};

class ZlgCan : public CanDriver
{
public:
    ZlgCan();

    virtual bool OpenDevice(QString sDevName,const sCanBaud mBaud);
    virtual bool CloseDevice();
    virtual bool SetBaud(uint32_t uBaud);
    virtual bool FindDev(QStringList &DevList);
    virtual bool Send(const sCANObj &msg);
    virtual int Receive(sCANObj &msg,DWORD dwMilliseconds = -1);
    int GetDevInd(QString sDevName);
    virtual ULONG GetSta(void);
private:
    int m_devtype;
    int m_DevInd;
    int m_PortInd;
    ZlgCanSnd  mCanSnd;     //发送线程
};
#endif

#ifdef EN_VECTOR

#include "vxlapi.h"

class VectorCan : public CanDriver
{
public:
    VectorCan();

    virtual bool OpenDevice(QString sDevName,const sCanBaud mBaud);
    virtual bool CloseDevice();
    virtual bool SetBaud(uint32_t uBaud);
    virtual bool FindDev(QStringList &DevList);
    virtual bool Send(const sCANObj &msg);
    virtual int Receive(sCANObj &msg,DWORD dwMilliseconds = -1);
    virtual ULONG GetSta(void);
private:
    unsigned int m_xlChannelMask;//XLaccess         m_xlChannelMask;//XLaccess类型处理出错
    XLportHandle m_xlPortHandle;
    HANDLE       hMsgEvent;
    bool isCantransceiver(unsigned short transceiverType);
};
#endif

#endif // CANDRIVER_H
